package com.basiclib.base

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import com.basiclib.inter.IModel
import com.basiclib.inter.IMvpView
import com.basiclib.inter.IPresenter
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import java.lang.ref.WeakReference

open class BasePresenter<V : IMvpView, M : IModel> constructor(var mModel: M) : IPresenter<V>, LifecycleObserver {

    protected var mCompositeDisposable: CompositeDisposable? = null
    val mRootView: V?
        get() = viewReference?.get()

    var viewReference: WeakReference<V>? = null
    var modelReference: WeakReference<M>? = null

    override fun attachView(view: V) {
        if (!isViewAttached) {
            viewReference = WeakReference(view)
            registerLifecycle()
        }
    }

    override fun registerLifecycle() {
        //将 LifecycleObserver 注册给 LifecycleOwner 后 @OnLifecycleEvent 才可以正常使用
        if (mRootView != null && mRootView is LifecycleOwner) {
            (mRootView as LifecycleOwner).lifecycle.addObserver(this)
            if (mModel != null && mModel is LifecycleObserver) {
                (mRootView as LifecycleOwner).lifecycle.addObserver(mModel as LifecycleObserver)
            }
        }
    }

    private val isViewAttached: Boolean
        get() = viewReference != null && viewReference!!.get() != null


    override fun onStart() {
        //将 LifecycleObserver 注册给 LifecycleOwner 后 @OnLifecycleEvent 才可以正常使用
        if (mRootView != null && mRootView is LifecycleOwner) {
            (mRootView as LifecycleOwner).lifecycle.addObserver(this)
            if (mModel != null && mModel is LifecycleObserver) {
                (mRootView as LifecycleOwner).lifecycle.addObserver(mModel as LifecycleObserver)
            }
        }
    }

    override fun onResume() {
    }

    override fun onPause() {
    }

    override fun onStop() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    internal fun onDestroy(owner: LifecycleOwner) {
        /**
         * 注意, 如果在这里调用了 [.onDestroy] 方法, 会出现某些地方引用 `mModel` 或 `mRootView` 为 null 的情况
         * 比如在 [RxLifecycle] 终止 [Observable] 时, 在 [io.reactivex.Observable.doFinally] 中却引用了 `mRootView` 做一些释放资源的操作, 此时会空指针
         * 或者如果你声明了多个 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 时在其他 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
         * 中引用了 `mModel` 或 `mRootView` 也可能会出现此情况
         */
        owner.lifecycle.removeObserver(this)
    }

    override fun onDestroy() {
        unDispose()//解除订阅
        viewReference?.clear()
        modelReference?.clear()
        viewReference = null
        modelReference = null
        this.mModel.onDestroy()
        this.mCompositeDisposable = null
    }

    fun addDispose(disposable: Disposable) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = CompositeDisposable()
        }
        mCompositeDisposable?.add(disposable)//将所有 Disposable 放入集中处理
    }

    fun unDispose() {
        mCompositeDisposable?.clear()
    }

}